package one.stand.controller.supplier;

import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.jmp.api.dto.*;
import com.jmp.autocofiguration.web.interceptor.SecurityAuthCheck;
import com.jmp.base.dto.*;
import com.jmp.feign.CardFeign;
import com.jmp.feign.CompanyFeign;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import one.stand.dto.*;
import one.stand.mapper.SeeRecordApiCrmAppMapper;
import one.stand.mapper.SeeRecordPublicMapper;
import one.stand.model.*;
import one.stand.service.BusinessCardBaseService;
import one.stand.service.CompanyBaseService;
import one.stand.service.user.MenuService;
import one.stand.service.user.UserAdminService;
import one.stand.util.AssertUtil;
import one.stand.util.OneListUtil;
import one.stand.util.RequestContext;
import one.stand.util.RequestContextHolder;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

/**
 * @author cjr
 */
@Api(description = "员工管理")
@RestController
@RequestMapping("/card")
public class CardController {

    @Autowired
    private CardFeign cardFeign;
    @Autowired
    private CompanyFeign companyFeign;

    @Autowired
    private BusinessCardBaseService businessCardBaseService;
    @Autowired
    private CompanyBaseService companyBaseService;
    @Autowired
    private SeeRecordPublicMapper seeRecordPublicMapper;
    @Autowired
    private UserAdminService userAdminService;
    @Autowired
    private MenuService menuService;

    @Autowired
    private SeeRecordApiCrmAppMapper seeRecordApiCrmAppMapper;

    @ApiOperation("1员工列表")
    @GetMapping("")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<CardResponse> list(@RequestAttribute PageRequest request) {
        final Integer optCompanyId = RequestContextHolder.getRequestContext().getUser().getCompanyId();

        Company company = companyBaseService.getById(optCompanyId);

        CardListDto cardListDto = CardListDto.builder()
                .companyId(optCompanyId)
                .status(1)
                .build();
        cardListDto.setPageNum(request.getPageNum());
        cardListDto.setPageSize(request.getPageSize());
        ResultModel<CardListVo> cardListVoResultModel = cardFeign.list(cardListDto);
        AssertUtil.isTrue(cardListVoResultModel);
        PageResponse2<CardResponse.Card> cardPage = ConvertUtils.page2(cardListVoResultModel.getData().getCardPage(), card -> {
            return CardResponse.Card.builder()
                    .cardId(card.getCardId())
                    .logo(card.getLogo())
                    .name(card.getName())
                    .position(card.getPosition())
                    .viewUser(seeRecordPublicMapper.selectVisitUser(Long.valueOf(card.getCardId())))
                    .viewNum(seeRecordPublicMapper.selectVisitNum(Long.valueOf(card.getCardId())))
                    .delFlag(BooleanUtils.toInteger(!company.getUserId().equals(card.getUserId())))//管理员不可移除
                    .build();
        });

        CompanyServiceDto companyServiceDto = companyBaseService.getService(optCompanyId);

        CardResponse response = CardResponse.builder()
                .cardNumTotal(companyServiceDto.getCurrentNum())
                .cardNumUnused(companyServiceDto.getAvailableNum())
                .cardNumUsed(companyServiceDto.getCurrentNum() - companyServiceDto.getAvailableNum())
                .cardPage(cardPage)
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation("1员工移除")
    @PostMapping("remove")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel remove(@RequestAttribute CardRemoveRequest request) {
        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();
        ResultModel resultModel = companyFeign.quit(CompanyQuitRequest.builder()
                .cardId(request.getCardId())
                .myCardId(optUser.getCardId())
                .build());
        AssertUtil.isTrue(resultModel);

        return ResultModel.success();
    }

    @ApiOperation(value = "1添加员工")
    @GetMapping("/add")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<CardAddResponse> cardUrl() {
        final RequestContext.User optUser = RequestContextHolder.getRequestContext().getUser();

        BusinessCard card = businessCardBaseService.getCustomer(optUser.getCardId());
        Company company = companyBaseService.getById(optUser.getCompanyId());

        CardAddResponse response = CardAddResponse.builder()
                .title("邀请加入企业")
                .memo(card.getName() + "邀请你加入" + company.getCompanyName())
                .url("https://card.hongmushichang.com/hmmpDownload.html")
                .shareImg(card.getLogo())
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "1员工详情")
    @GetMapping("/info")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<CardInfoResponse> info(@RequestAttribute CardInfoRequest request) {
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<CrmSeeRecordModel> seeRecordModels = seeRecordApiCrmAppMapper.selectUserList(request.getCardId());
        PageResponse2<CardInfoResponse.Customer> userList = ConvertUtils.page2(seeRecordModels, crmSeeRecordModel -> {
            UserDto user = userAdminService.get(crmSeeRecordModel.getUserId().intValue());
            BusinessCard card = businessCardBaseService.getByUserId(user.getUserId());
            return CardInfoResponse.Customer.builder()
                    .userId(user.getUserId())
                    .logo(user.getUserImg())
                    .name(user.getName())
                    .count(crmSeeRecordModel.getRanking())
                    .time(crmSeeRecordModel.getCreateTime().getTime())
                    .chatId(String.valueOf(user.getUserId()))
                    .wechatId(Objects.nonNull(card) ? card.getPersonalWx() : null)
                    .phone(user.getPhone())
                    .build();
        });

        CardInfoResponse response = CardInfoResponse.builder()
                .customerPage(userList)
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation("2员工申请列表")
    @GetMapping("apply")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<CardApplyResponse> apply(@RequestAttribute PageRequest request) {
        final Integer optCompanyId = RequestContextHolder.getRequestContext().getUser().getCompanyId();
        CardListDto cardListDto = CardListDto.builder()
                .companyId(optCompanyId)
                .status(0)
                .build();
        cardListDto.setPageNum(request.getPageNum());
        cardListDto.setPageSize(request.getPageSize());
        ResultModel<CardListVo> cardListVoResultModel = cardFeign.list(cardListDto);
        AssertUtil.isTrue(cardListVoResultModel);
        PageResponse2<CardApplyResponse.Card> cardPage = ConvertUtils.page2(cardListVoResultModel.getData().getCardPage(), card -> {
            return CardApplyResponse.Card.builder()
                    .cardId(card.getCardId())
                    .logo(card.getLogo())
                    .name(card.getName())
                    .time(card.getTime().getTime())
                    .build();
        });
        CardApplyResponse response = CardApplyResponse.builder()
                .cardPage(cardPage)
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation("2员工申请:同意")
    @PostMapping("apply/agree")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel applyAgree(@RequestAttribute CardApplyAgreeRequest request) {

        ResultModel resultModel = cardFeign.applyAgree(CardApplyAgreeDto.builder().cardId(request.getCardId()).build());
        AssertUtil.isTrue(resultModel);

        return ResultModel.success();
    }

    @ApiOperation("2员工申请:拒绝")
    @PostMapping("apply/refuse")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel applyRefuse(@RequestAttribute CardApplyRefuseRequest request) {

        ResultModel resultModel = cardFeign.applyRefuse(CardApplyRefuseDto.builder()
                .cardId(request.getCardId())
                .build());
        AssertUtil.isTrue(resultModel);

        return ResultModel.success();
    }

    @ApiOperation("3员工权限")
    @GetMapping("auth")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<CardAuthResponse> auth(@RequestAttribute PageRequest request) {
        final Integer optCompanyId = RequestContextHolder.getRequestContext().getUser().getCompanyId();
        Company company = companyBaseService.getById(optCompanyId);
        CardListDto cardListDto = CardListDto.builder()
                .companyId(optCompanyId)
                .status(1)
                .build();
        cardListDto.setPageNum(request.getPageNum());
        cardListDto.setPageSize(request.getPageSize());
        ResultModel<CardListVo> cardListVoResultModel = cardFeign.list(cardListDto);
        AssertUtil.isTrue(cardListVoResultModel);
        PageResponse2<CardAuthResponse.Card> cardPage = ConvertUtils.page2(cardListVoResultModel.getData().getCardPage(), card -> {
            return CardAuthResponse.Card.builder()
                    .cardId(card.getCardId())
                    .logo(card.getLogo())
                    .name(card.getName())
                    .position(card.getPosition())
                    .setFlag(BooleanUtils.toInteger(!company.getUserId().equals(card.getUserId())))
                    .build();
        });
        CardAuthResponse response = CardAuthResponse.builder()
                .cardPage(cardPage)
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation("3员工权限:详情")
    @GetMapping("auth/info")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel<CardAuthInfoResponse> authInfo(@RequestAttribute CardAuthInfoRequest request) {
        List<MenuTreeDto> menuTreeDtos = menuService.getAll(null, MenuService.TYPE_CRN_APP_NEW);
        BusinessCard card = businessCardBaseService.getCustomer(request.getCardId());
        List<Integer> menuOpen = menuService.getOpen(card.getUserId());
        List<CardAuthInfoResponse.Auth> auths = ConvertUtils.list(menuTreeDtos, menuTreeDto -> {
            boolean isOpen = true;
            List<CardAuthInfoResponse.Auth> childList = null;
            if (OneListUtil.isNotEmpty(menuTreeDto.getMenus())) {
                childList = Lists.newArrayList();
                boolean isOpenChild = true;
                for (MenuTreeDto childDto : menuTreeDto.getMenus()) {
                    isOpenChild = menuOpen.contains(childDto.getMenu().getMenuId());
                    if (isOpen) {
                        isOpen = isOpenChild;
                    }
                    childList.add(CardAuthInfoResponse.Auth.builder()
                            .authId(childDto.getMenu().getMenuId())
                            .authName(childDto.getMenu().getValue())
//                            .authIcon(childDto.getMenu().getIcon())
                            .open(isOpenChild ? 1 : 0)
                            .build());
                }
            }
            return CardAuthInfoResponse.Auth.builder()
                    .authId(menuTreeDto.getMenu().getMenuId())
                    .authName(menuTreeDto.getMenu().getValue())
//                    .authIcon(menuTreeDto.getMenu().getIcon())
                    .open(isOpen ? 1 : 0)
                    .authList(childList)
                    .build();
        });

        CardAuthInfoResponse response = CardAuthInfoResponse.builder()
                .auths(auths)
                .build();
        return ResultModel.success(response);
    }

    @ApiOperation(value = "3员工权限:修改")
    @PostMapping("/auth/save")
    @SecurityAuthCheck(company = true, card = true)
    public ResultModel authSave(@RequestAttribute CardAuthSaveRequest request) {
        BusinessCard card = businessCardBaseService.getCustomer(request.getCardId());
        UserDto user = userAdminService.get(card.getUserId());
        AssertUtil.isFalse(user.isBoss(), "不能编辑管理员权限");

        menuService.update(card.getUserId(), request.getAuthIds(), request.getOpen() == 1);
        return ResultModel.success();
    }
}
